package com.lewis.config;

import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.StringUtils;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.fasterxml.jackson.databind.util.JSONPObject;
import com.lewis.realm.CustomeRealm;


/**
 * shiro配置信息类
 * @author jiaqi.liu
 *
 */
@Configuration
public class ShiroConfig{
	
	/**
	 * 将加密凭证注入
	 * @return
	 */
	@Bean(name="credentialsMatcher")
	public CredentialsMatcher credentialsMatcher(){
		  HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();  
	       hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;  
	       hashedCredentialsMatcher.setHashIterations(3);//散列的次数相当于 md5(md5(""));  
		return hashedCredentialsMatcher;
	}
	

	/**
	 * 将自定义的Realm注入容器并为其设置加密凭证
	 * @return
	 */
	@Bean(name="customeRealm")
	public CustomeRealm customeRealm(@Qualifier("credentialsMatcher")CredentialsMatcher credentialsMatcher){
		
		CustomeRealm realm=new CustomeRealm();
		realm.setCredentialsMatcher(credentialsMatcher);
		return realm;
	}
	
	
	/**
	 * cookie
	 * @return
	 */
	/*@Bean(name="simpleCookie")
	public SimpleCookie simpleCookie(){
		SimpleCookie cookie=new SimpleCookie("remberMe");
		cookie.setHttpOnly(true);
		cookie.setMaxAge(20000000);
		cookie.setDomain("localhost");
		return cookie;
	}*/
	
	/**
	 * RememberMeManager
	 * @return
	 */
	/*@Bean(name="rememberMeManager")
	public RememberMeManager rememberMeManager(@Qualifier("simpleCookie")SimpleCookie simpleCookie){
		CookieRememberMeManager rememberMeManager =new CookieRememberMeManager();
		rememberMeManager.setCookie(simpleCookie);
		return rememberMeManager;
	}*/
	
				
	/**
	 * 注入配置安全管理器SecurityManager的bean
	 * @param realm 自定义的realm
	 * @return
	 */
	@Bean(name="securityManager")
	public SecurityManager securityManager(@Qualifier("customeRealm")CustomeRealm realm){
		
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		     //配置realm,session管理器,cookie,缓存管理器
			  securityManager.setRealm(realm);
			  //securityManager.setCacheManager(CacheManager);
			  //securityManager.setRememberMeManager(null);
			  securityManager.setSessionManager(new DefaultWebSessionManager());
		 return securityManager;
	}
	
	 /**  
     *  shiro aop.  
     * @param securityManager  
     * @return  
     */  
    @Bean  
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){  
       AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();  
       authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);  
       return authorizationAttributeSourceAdvisor;  
    }
  
    @Bean
    public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager securityManager) {
    	
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String, String> map = new LinkedHashMap<String, String>();
        //swagger-ui资源
        map.put("/swagger-ui.html", "anon");
        map.put("/swagger-resources", "anon");
        map.put("/v2/api-docs", "anon");
        map.put("/webjars/springfox-swagger-ui/**", "anon");
        map.put("/configuration/**", "anon");
        //login，register和认证接口
        map.put("/doLogin", "anon");
        map.put("/register", "anon");
        map.put("/**", "selfFilter");
       
        //配置自定义的filter定义未认证，未授权的异常
        AuthorizationFilter filter=new AuthorizationFilter(){
         	
	        	@Override
	        	protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
	        			throws Exception {
	        		System.out.println("method-----------------------------isAccessAllowed");
	        		
	        		Subject subject = getSubject(request, response);
	        		if(null!=subject.getPrincipals())
	        			return true;//访问通过
	        		return false;//访问拒绝
	        	}
	        	/**
	        	 * 表示访问拒绝时是否自己处理，
	        	 * 如果返回true表示自己不处理且继续拦截器链执行，
	        	 * 返回false表示自己已经处理了（比如重定向到另一个页面）。
	        	 */
	         	protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
	         		
	                 Subject subject = getSubject(request, response);
	                 if (subject.getPrincipal() == null) {
	                	 WebUtils.toHttp(response).sendError(200,"please doLogin First");
	                 } 
	                 return false;
	             }
         	};
        Map<String, Filter> filterMap=new HashMap<String,Filter>();
        filterMap.put("selfFilter", filter);
        shiroFilterFactoryBean.setFilters(filterMap);
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }
   

}
